/**
 * vuex全局状态管理模式，所有的组件可以获取里面的数据，并且通过提交里面的方法，修改里面的数据
 */
import { createStore,Commit} from "vuex";
import { GlobalDataProps,GlobalErrorsProps} from "@/utlis/type";
import httpInstance from "@/axios";
//发起异步的axios的get请求,使用await
const getAndCommit = async (url:string,mutationName:string,commit:Commit)=>{
    const {data} = await httpInstance.get(url)
    commit(mutationName,data)
}
//发起异步的axios的post请求,使用await
const postAndCommit = async (url:string,mutationName:string,commit:Commit,payload:any)=>{
    const {data} = await httpInstance.post(url,payload)
    commit(mutationName,data)
    return data
}
const store = createStore<GlobalDataProps>({
    //存储数据
    state:{
        error:{status:false},
        token:localStorage.getItem('token') || '',
        loading:false,
        columns:[],
        posts:[],
        user:{isLogin:false},
        article:{}
    },
    //同步修改数据
    mutations:{
        //1.登录
        login(state,result){
            state.token = result.data.token
            //将token存储在localstorage中
            localStorage.setItem('token',state.token)
             //在全局设置一个请求头，在后面发送请求的过程中都会携带请求头,
            httpInstance.defaults.headers.common['Authorization'] = `Bearer ${state.token}`
        },
        //2.获取columns的列表数据
        fetchColumns(state,result){
            state.columns = result.data.list
        },
        //3.获取指定id的专栏信息
        fetchColumnById(state,result){
            state.columns = [result.data]
        },
        //4.获取指定专栏的所有详细的文章信息
        fetchPostById(state,result){
            state.posts = result.data.list
        },
        //5、改变loading的值,在发送异步请求的过程中，显示loading动画
        setLoading(state,status){
            state.loading = status
        },
        //6、获取当前用户的信息
        fetchCurrentUser(state,result){
            state.user ={isLogin:true,...result.data}
        },
        //7、当用户的登录报错或者token失效的处理
        setError(state,e:GlobalErrorsProps){
            state.error = e
        },
        //8、注册新用户
        register(state,result){
            console.log("注册成功")
        },
        //9、退出登录
        logout(state){
            state.token = ''
            state.user.isLogin = false
            localStorage.removeItem('token')
            delete httpInstance.defaults.headers.common.Authorization
        },
        //10、新建文章,将新建文章压入栈中
        createPost(state,result){
            state.posts.push(result)
        },
        //11、获取单个文章的数据
        fetchArticleDetail(state,result){
            state.article = result.data
        }
    },
    //发起异步请求
    actions:{
        //1、发起专栏列表数据的异步请求
        fetchColumns(context){
            return  getAndCommit('/columns','fetchColumns',this.commit)
        },
        //2、发起指定专栏数据的异步请求
        fetchColumnById({commit},cid){
            return getAndCommit(`/columns/${cid}`,'fetchColumnById',commit)
        },
        //3、发起文章列表数据的异步请求
        fetchPostById({commit},cid){
            return getAndCommit(`/columns/${cid}/posts`,'fetchPostById',commit)
        },
        //4、发起登录的异步请求
        login({commit},payload){
            return postAndCommit('/user/login','login',commit,payload)
        },
        //5、发起当前用户信息的异步请求
        fetchCurrentUser({commit}){
            return getAndCommit('/user/current','fetchCurrentUser',commit)
        },
        //6、先发起登录的请求，然后再获取当前用户的信息【注意：登录成功后，才会获取当前用户的信息】
        loginAndFetch({dispatch},payload){
            return dispatch('login',payload).then(()=>{
                return dispatch('fetchCurrentUser')
            })
        },
        //7、发起注册新用户的异步请求
        register({commit},payload){
            return postAndCommit('/users','register',commit,payload)
        },
        //8、发起新建文章的异步请求
        createPost({commit},payload){
            return postAndCommit('/posts','createPost',commit,payload)
        },
        //9、发起获取单个文章的异步请求
        fetchArticleDetail({commit},id){
            return getAndCommit(`/posts/${id}`,'fetchArticleDetail',commit)
        }
    },
    //相当于计算属性，主要是利用其返回值
    getters:{
        //根据id,查询对应的专栏的信息
        getColumnById:(state) => (id:string) =>{
            return state.columns.find(item => item._id === id)
        },
        //根据cid,过滤对应的详情的信息
        getPostsByCid:(state) =>(cid:string) =>{
            return state.posts.filter(post => post.column ===  cid)
        }
        
    }
})
export default store